"""1.1.1  一维数组与常用操作"""
import pandas as pd
import matplotlib.pyplot as plt

# 列名与数据对齐显示（设置输出结果列对齐）
pd.set_option('display.unicode.ambiguous_as_wide', True)
pd.set_option('display.unicode.east_asian_width', True)

# 使用列表来生成一维数组Series，若无索引会默认自动创建从0开始的非负整数作为索引，列表中的数据作为值
s1 = pd.Series(range(1, 20, 5))
# 使用字典来生成一维数组Series，字典的键作为Series的索引，值作为Series的值
s2 = pd.Series({'语文': 90, '数学': 92, 'Python': 98, '物理': 87, '化学': 92})
# 根据指定索引来修改对应的值
s1[3] = -17  # 根据缺省索引
s2['语文'] = 94  # 根据字典的键


## 对一维数组s1进行相关操作
print('s1的原始数据'.ljust(20, '='))
print(s1)  # 输出一维数组s1

print('s1的数据直方图'.ljust(20, '='))
s1.hist()  # 生成一维数组s1的数据直方图
plt.show()  # 显示直方图

print('对s1的所有数据取绝对值'.ljust(20, '='))
print(abs(s1))  # abs绝对值运算符，对一维数组s1中的所有数据取绝对值并输出

print('s1的所有值加5'.ljust(20, '='))
print(s1 + 5)  # 加法运算，对s1中的所有数据加5并输出

print('s1的每行索引前加上数字2'.ljust(20, '='))
print(s1.add_prefix(2))  # 对s1的每行索引前加上数字2并输出


## 对一维数组s2进行相关操作
print('s2的原始数据'.ljust(20, '='))
print(s2)  # 输出一维数组s2

print('s2的数据直方图'.ljust(20, '='))
s2.hist()  # 生成一维数组s2的数据直方图
plt.show()  # 显示直方图

print('s2的每行索引后加上_张三'.ljust(20, '='))
print(s2.add_suffix('_张三'))  # 在一维数组s2的每行索引后加上_张三，并输出

print('s2的最大值索引'.ljust(20, '='))
print(s2.argmax())  # argmax()函数是找出最大值所在的索引，输出s2中最大值的索引

print('测试s2的数据是否在指定区间内'.ljust(20, '='))
print(s2.between(90, 94))  # 测试s2的数据是否在指定区间内，对每个数据进行判断，输出真假

print('s2中90分以上的数据'.ljust(20, '='))
print(s2[s2 > 90])  # 输出s2中大于90分的数据

print('s2中大于中值的数据'.ljust(20, '='))
print(s2[s2 > s2.median()])  # 输出s2中大于中值的数据，median()是用来求中值的
print("s2的中值：", s2.median())

print('s2与数字之间的运算'.ljust(20, '='))
print(round((s2 ** 0.5) * 10, 1))  # 对s2中的值进行相关数字运算并保留一位小数输出

print('s2的中值'.ljust(20, '='))
print(s2.median())  # 输出s2的中值，median()是用来求中值的

print('s2中最小的的两个值'.ljust(20, '='))
print(s2.nsmallest(2))  # 输出s2中最小的两个值，nsmallest()是用来选出最小的值，可以指定个数



## 两个等长Series对象之间可以进行四则运算和幂运算
# 只对两个Series对象中都有的索引对应的值进行计算
# 非共同索引对应的值为控制NaN
print('两个一维数组Series对象相加'.ljust(20, '='))
print(pd.Series(range(5)) + pd.Series(range(5, 10)))  # 两个Series对象的值相加，前者为（0，1，2，3，4）后者为（5，6，7，8，9）.要求Series等长，且类型相同


## pipe()方法可以实现函数链式调用的功能
print('每个值取平方再对5取余数'.ljust(20, '='))
print(pd.Series(range(5)).pipe(lambda x, y, z: (x ** y) % z, 2, 5))  # Series中的值作为x，按照lambda表达式进行有关运算
print('每个值加3后再乘3'.ljust(20, '='))
print(pd.Series(range(5)).pipe(lambda x: x + 3).pipe(lambda x: x * 3))  # Series中的值作为x，按照lambda表达式进行有关运算，其中pipe()可以实现函数链式调用


## apply()方法用来对Series对象的值进行函数运算
print('每个值加3'.ljust(20, '='))
print(pd.Series(range(5)).apply(lambda x: x + 3))  # Series中的值作为x，按照lambda表达式进行有关运算

print('指标：标准差、无偏方差、无偏标准差'.ljust(20, '='))
print(pd.Series(range(5)).std())  # Series中的值的标准差
print(pd.Series(range(5)).var())  # Series中的值的无偏方差
print(pd.Series(range(5)).sem())  # Series中的值的无偏标准差

print('查看是否存在等价于True的值'.ljust(20, '='))
print(any(pd.Series([3, 0, True])))  # any()函数如果可迭代对象iterables中存在元素为True则返回True，全为False则返回False
